declare
Rules=
rules(% If the goal is to put Y on X and X supports Y,
      % then remove that goal
      fun {$} X Y Xr in
         [g(stack(X|Y|Xr)) f(supports(X Y))] #
         [remove(g(stack(X|Y|Xr))) add(g(stack(Y|Xr)))]
      end
      % If the goal is to put Y on X and X and Y are free,
      % then put Y on top of X
      fun {$} X Y Z Xr in
         [g(stack(X|Y|Xr))
          'not'(fun {$} U in f(supports(X U)) end)
          'not'(fun {$} U in f(supports(Y U)) end)
          f(supports(Z Y))] #
         [remove(f(supports(Z Y))) add(f(supports(X Y)))
          remove(g(stack(X|Y|Xr))) add(g(stack(Y|Xr)))]
      end
      % If the goal is to put Y on X and X supports Z,
      % then create a new goal to move Z to the floor
      fun {$} X Y Xr Z in
         [g(stack(X|Y|Xr)) f(supports(X Z)) notEqual(Y Z)
          'not'(fun {$} g(move(Z)) end)] #
         [add(g(move(Z)))]
      end
      fun {$} X Y Xr in
         [g(stack(_|X|Xr)) f(supports(X Y))
          'not'(fun {$} g(move(Y)) end)] #
         [add(g(move(Y)))]
      end
      fun {$} X in
         [g(stack([X])) f(supports(floor X))
          'not'(fun {$} U in f(supports(X U)) end)] #
         [remove(g(stack([X])))]
      end
      fun {$} X Y in
         [g(move(X)) f(supports(X Y))
          'not'(fun {$} g(move(Y)) end)] #
         [add(g(move(Y)))]
      end
      fun {$} X Y in
         [g(move(X))
          'not'(fun {$} U in f(supports(X U)) end)
          f(supports(Y X))] #
         [remove(f(supports(Y X))) add(f(supports(floor X)))
          remove(g(move(X)))]
      end)
